Skip to content

pull in latest upstream#2

Open
TtheBC01 wants to merge 799 commits into
1Shot-API:mainfrom
x402-foundation:main
Open

pull in latest upstream#2
TtheBC01 wants to merge 799 commits into
1Shot-API:mainfrom
x402-foundation:main

Conversation

@TtheBC01

Copy link
Copy Markdown

Description

Tests

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits
  • I added a changelog fragment for user-facing changes (docs-only changes can skip)

Must-be-Ash and others added 18 commits May 2, 2026 16:25
The /api/x402/demo endpoint did not help the isitagentready.com scanner
detect x402 support. Removing dead code.
* docs: add builder_code.md spec

* support services array
* spec + sdk

* add auto recover and topUp; add filestorage

* add session manager

* fix nonce reset

* add cooperativeWithdraw to spec/contract

* add cooperative withdraw to sdk

* update sdk to match spec v1.2

* change to auto-generated getters

* improve server devx

* improve client devx

* added concurrent request example

* minor fixes

* add cas

* add streaming example

* rename files to batched*

* updated scheme name deferred -> batched

* update to new contracts

* align paymentresponse.extra for all payloads

* fix recovery after refund

* fix withdraw -> refund flag

* fix channel manager

* rename to batch-settlement

* align with cloudflare specs

* remove claim/refund without sign

* add tx sim

* improve specs

* specs ready

* add unit/integration tests

* fix tests

* improve typing, remove dead code

* add readmes

* add e2e tests

* fix fileStorage

* increase depositMultiplier for streaming

* refund without paid request

* refactor convertToTokenAmount

* refactor scheme

* fix recovery for refund flow

* refactor client scheme

* rename session -> channel

* remove chargedCumulativeAmount from deposit payload

* scheme hook adapters

* add enrichSettlementPayload/enrichSettlementResponse hooks

* move batch-settlement scheme to scheme hook adapters and enrichSettlementResponse

* refactor refund and other payloads

* add client hook adapters

* align payment-response shapes

* move corrective 402 info from errorDetails to requirements.extra.channelState

* fix corrective deposit flow

* update to latest deployment and change channelId computation to EIP-712

* add hook to handle route handler failures

* add atomic channel update and request context primitives

* guard channels with pending reservations

* fix concurrent claim/settle

* skip facilitator and verify locally if onchain state fresh

* add redis storage

* add fullstack next example with redis and fix settlementOverride for next package

* align payment-response for all payloads

* add permit2 support and fix extra enrichment for nested objects

* fix DEPOSIT_WITNESS_TYPE_STRING

* test client state-loss recovery scenario in e2e

* fix recovery for axios

* improve channel manager

* update client deposit policy

* clean up examples

* add to testnet facilitator

* update READMEs

* for the culture

* add changesets

* update to latest deployment

* align error codes

* remove receiverAuthorizer fallback
* feat: added cdk to example

* feat: pin x402 package versions

* feat: updated pin to float patch
* batch-settlement on EVM

* update refund flow and payloads

* move corrective 402 info from errorDetails to requirements.extra.ChannelState and compute channelID from EIP712Hash

* align payment-response for all payloads

* post audit updates

* add deposit collector addresses

* update error codes
* docs: add repo move note to README (#40)

* add service metadata on resource to all 3 SDKs

* lint

* changelog

* review: harden iconUrl validators + tighten signatures

* review: constrain serviceName/tags to printable ASCII

* add checks to harden iconurl + tag/name validators

* update v2 spec + python lint

* python format

---------

Co-authored-by: Ash <105402607+Must-be-Ash@users.noreply.github.com>
Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* Update docs/sdk-features.md

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/sdk-features.md

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…ecoin (Permit2 + EIP-2612) (#2038)

* feat(evm): add Radius Network and Radius Testnet default stablecoin (Permit2 + EIP-2612)

Add SBC as the default stablecoin for Radius Network (eip155:723487)
and Radius Testnet (eip155:72344) across Go, TypeScript, and Python SDKs.

SBC does not support EIP-3009, so Permit2 is the required transfer
method. SBC does support EIP-2612 permit() for gasless approval.

* docs: add Radius default-stablecoin entries to user-facing docs

* chore(paywall): update generated Radius decimals
)

* add extension responses header logging

* add changelogs and log whole sanitized header

* remove envelope attachment

* use list instead of map

* update changelog entries

* add facilitator examples
* feat: add batch-settlement implementation to Go SDK

* feat: add batch-settlement examples for go sdk

* feat: updated typescript examples to match go examples

* feat: add e2e testing for batch-settlement in go

* Batch-settlement: go-ts parity (#2227)

* fix PendingRequest and refund cleanup

* fix lint

* remove duplicate payer info from storage

* fix PAYMENT-RESPONSE field ordering

* clean up comments

* consolidate ProcessSettlementWithExtensions into ProcessSettlement

---------

Co-authored-by: phdargen <p.dargent@cern.ch>
* feat: add TVM exact-payment mechanism to Python SDK

- add TVM exact client, server, and facilitator implementations
- add TVM signers, codecs, provider, and settlement helpers
- add unit and integration coverage for TON testnet/mainnet flows
- add Python examples and e2e wiring for TVM

* Enable TVM exact flows in Python e2e and tighten facilitator validation

Add TVM support to the Python e2e clients and servers, switch TVM usage to direct `ExactTvm*Scheme` registration after removing the old register helpers, and refresh docs/examples for testnet setup.
Also reject exact TVM settlements with excessively large attached TON amounts and cover the new validation with tests.

* fix: clarify minimum balance of the facilitator

* refactor(tvm): release settlement cache entry on confirmed settlement

  On-chain seqno advances after a successful relay, so any retry of the same settlement BOC will fail at the W5 contract's seqno check regardless of the dedup reservation. Drop the entry as soon as the confirmation worker records success, so the invariant becomes "every is_duplicate=False is paired with a release" and TTL pruning is left as a crash safety-net only.

* feat(tvm): add TonAPI provider support

* feat(tvm): update e2e tests  to make them compatible with new providers

* fix(tvm): update timeouts

* fix(tvm): increase http client timeout

* fix(tvm): align unit tests

* revert(e2e): remove .env-local config load

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#2242)

Tightens the viem floor in every package.json that lists viem (41 refs
across 40 files), refreshes all three lockfiles so every direct viem
resolution reads 2.48.11, and regenerates the paywall bundled templates
so the EVM/SVM/AVM bundles match the new viem chain database.

## Why floor-tightening matters

PR #2013 bumped lockfiles to 2.47.14, but later PRs (#2061, #2197, ...)
added sub-packages with ^2.39.x / ^2.43.x floors. pnpm re-resolved on
subsequent installs and the solver picked the lowest acceptable version
across constraints. ^-ranges with low floors do NOT preserve a bump --
lockfile refreshes erode the floor.

This PR fixes that incomplete tightening from #2013 by raising every
floor to ^2.48.11. The same regression will recur if any future PR adds
a viem-using sub-package with a lower floor. Gate criterion: new
packages must use ^2.48.11 (or tighter) for viem.

## Acceptance verification

- pnpm install --frozen-lockfile clean across typescript/,
  examples/typescript/, and e2e/.
- pnpm format:check, lint:check, build, test green for typescript/.
- pnpm format:check, lint:check green for examples/typescript/.
- All direct viem resolutions read 2.48.11 in all three workspaces.
- Paywall bundled templates regenerated via
  pnpm --filter @x402/paywall run build:paywall.
feyyazcigim and others added 30 commits July 13, 2026 09:11
* docs(facilitators): add Solvador to facilitators list

* docs(facilitators:solvador): add NEAR support
…t error (#2721)

* fix(python/flask): return 500 (and log) on unexpected settlement error

* chore(changelog): name flask settlement fragment by PR number

* fix(python/flask): surface unexpected settlement error as 402 + PAYMENT-RESPONSE (mirror #2622)

* fix(python/flask): use canonical unexpected_settle_error reason (parity with #2622)

* style(python): apply ruff format to test_flask.py

* chore(python): restore uv.lock to main (no dependency changes in this PR)

* chore(python): leave uv.lock untouched (no dependency changes)
* verify aptos sign

* verify aptos sign
* feat(xrpl): add exact scheme TypeScript reference implementation

Implements specs/schemes/exact/scheme_exact_xrpl.md as @x402/xrpl with
client, resource-server, and facilitator schemes for payer-signed XRPL
Payment transactions:

- sequence and ticketSequence asset transfer methods with the spec's
  resolution order, per-method verification (current account Sequence,
  ticket availability), and a createTickets utility
- extra.areFeesSponsored=false advertised via facilitator getExtra and
  enforced in envelope verification
- offline signature validation, NetworkID binding, InvoiceID invoice
  binding (Memos rejected), Delegate/Paths/DeliverMin/partial-payment
  rejection, fee caps, LastLedgerSequence expiry policy, and simulation
  (signature fields stripped: the XRPL simulate API only accepts
  unsigned transactions)
- settlement re-verifies, submits, and requires validated tesSUCCESS
- XRP drops and issued-currency decimal value amounts compared with
  exact decimal arithmetic (no extra.decimals field)

The server scheme keeps enhancePaymentRequirements deterministic
(requirements are rebuilt per request), so invoice binding activates
only when the resource configuration provides extra.invoiceId.

Adds unit and integration tests, publish workflows, release-script and
changeset fixed-group wiring, and the root test:integration filter.

* feat(e2e): wire XRPL into the e2e harness and participants

Adds the xrpl protocol family to the harness networks/types/env
plumbing, registers @x402/xrpl in the axios and fetch clients, the
express/fastify/hono/next servers (GET /exact/xrpl routes priced in
XRP drops), the TypeScript facilitator (keyless: the payer signs and
pays XRPL fees), and the mock facilitator supported response.

Verified locally against XRPL Testnet (xrpl:1) with funded faucet
accounts: pnpm test --testnet --families=xrpl --versions=2 passes all
10 scenarios (axios/fetch x express/fastify/hono/next incl. withX402).

* feat(examples): add XRPL to the advanced all_networks examples

Registers @x402/xrpl in the client, server, and facilitator
all_networks examples (alphabetical by network prefix), with
XRPL_SEED/XRPL_ADDRESS/XRPL_NETWORK/XRPL_WS_URL configuration.

* docs(examples): add XRPL setup to the advanced example READMEs

Document the XRPL environment variables, testnet faucet steps, and
reserve/trust line requirements in the advanced client, server, and
facilitator example READMEs, and add the matching .env-local entries.
The facilitator README also notes the keyless XRPL scheme (enabled via
XRPL_NETWORK), its /supported kind with areFeesSponsored=false, and the
xrpl:0 / xrpl:1 network identifiers.

* fix(typescript): regenerate pnpm-lock.yaml after rebase onto main

The website deprecation (#2794) removed the jiti-suffixed peer-dependency
variants that the @x402/xrpl importer entries resolved to. Re-resolve the
lockfile against the current workspace so frozen installs succeed.

* fix(xrpl): bind signatures to account authorization and harden verification

- Verify the embedded SigningPubKey is authorized for Account (master key
  pair unless disabled, or the configured regular key) via a validated
  account_info lookup. Offline signature validation only proves the blob
  was signed by its embedded key, and simulation strips signature fields,
  so an unauthorized signer previously passed /verify and failed at
  /settle with tefBAD_AUTH or tefMASTER_DISABLED.
- Reject single-signed blobs that carry a Signers array; the single
  signature does not cover Signers, so hybrid blobs still pass
  verifySignature.
- Fail closed on malformed extra.destinationTag in the facilitator,
  resource server, and client instead of silently skipping the tx-level
  binding.
- Correct the changeset wording: the server scheme passes through
  configured invoice ids, it does not generate them.
- Cover the new checks and previously untested spec rules in unit tests:
  envelope mismatches, NetworkID branches, XRP/IOU amount and SendMax
  variants, LastLedgerSequence bounds, InvoiceID mismatch, sequence 0,
  settle outcomes, and client-side NetworkID handling.

* test(xrpl): add env-gated live settlement integration test

Mirror the NEAR exact-near.live.test.ts pattern: when XRPL_PAYER_SEED and
XRPL_LIVE_PAYTO (or the e2e CLIENT_XRPL_SEED / SERVER_XRPL_ADDRESS names)
are set, drive the reference client, resource server, and keyless
facilitator end to end against a real network and assert the payTo XRP
balance increases by exactly the requested drops. Skipped when the
accounts are not configured, so it stays inert in CI.

Verified against XRPL Testnet: settled tx
6AF0A4F630F2B43CA44544D5246B58260A01860A3CCBB331625229CD78696791.

* fix(xrpl): mirror rippled signer-key ordering and require canonical signing keys

- Authorize the configured regular key before the master-disabled check,
  matching rippled's fixMasterKeyAsRegularKey ordering so legacy accounts
  whose RegularKey equals their own address are not wrongly rejected.
- Reject non-canonical SigningPubKey encodings (only 33-byte compressed
  secp256k1 or ed25519 keys) before signature validation; rippled refuses
  such keys at preflight, so accepting them would let verification pass
  for a transaction that can never settle.

* feat(xrpl): create tickets automatically for ticketSequence payments

When a ticketSequence payment finds no available ticket, the client now
creates tickets through the ClientXrplSigner abstraction instead of
throwing and requiring a manual createTickets() call. The new
ticketCreateCount option controls the policy: it defaults to 1, allows
up to 250 tickets per TicketCreate, and 0 restores the previous
fail-fast behavior for pre-provisioned setups. Available tickets are
still reused first and skip the creation transaction entirely.

- Widen ClientXrplSigner.sign from Payment to SubmittableTransaction so
  the same signer can sign TicketCreate; createTickets accepts the
  signer abstraction instead of an xrpl.js Wallet.
- Cover the default, configured, and disabled policies plus invalid
  counts in unit tests.

* fix(xrpl): return a stable reason code for unexpected verification failures

The verify() catch-all embedded the raw error message in the
invalidReason string (invalid_exact_xrpl_payload_malformed: <message>),
so integrators could not match on a stable code. Return
invalid_exact_xrpl_facilitator_error and carry the raw diagnostic text
separately in invalidMessage. Settlement submission errors keep the
existing transaction_failed: <diagnostic> reason.

* fix(xrpl): fail closed on missing or invalid IOU issuers

Issued-currency requirements and accepted payloads must both carry a
valid classic issuer address before the issuer comparison runs. Two
absent issuers previously compared equal and passed envelope
validation, and a single absent issuer surfaced as a confusing
mismatch. Missing or malformed issuers now return
invalid_exact_xrpl_iou_issuer_missing.

* fix(xrpl): set the custom-network NetworkID when building payments

The client validated that prepared transactions carried the correct
NetworkID on custom networks (id > 1024) but relied on the preparer to
add the field. Insert it while building the payment so the default and
custom preparers both start from a correct transaction; validation
still rejects preparers that remove or replace it.

* refactor(xrpl): reuse parseMoneyString from @x402/core

Replace the server scheme's hand-rolled money-string parsing with the
shared parseMoneyString helper used by the other mechanism packages,
aligning string-price edge-case handling with the rest of the SDK.

* test(e2e): cover both XRPL asset-transfer methods on every server

Replace the single /exact/xrpl route with explicit sequence and
ticketSequence endpoints on Express, Fastify, Hono, and Next (both the
proxy middleware and withX402), pinning extra.assetTransferMethod and
the issuer for issued-currency pricing in each route config. Teach the
harness that asset transfer methods are not EVM-only metadata: xrpl
endpoints resolve their declared method and default to sequence, and
the server proxy forwards the configured issuer.

* test(e2e): add a self-managed XRPL Testnet IOU fixture

pnpm xrpl:iou:setup creates or reuses dedicated Testnet issuer, payer,
and payee accounts, funds missing ones through the faucet, enables
DefaultRipple on the issuer, establishes the trust lines, and issues
test USD to the payer, replenishing it on re-runs. Credentials are
persisted only in the git-ignored e2e/.env with 0600 permissions,
seeds are never logged, and the script refuses to run unless the
connected ledger reports Testnet network id 1. Mask seed values
alongside private keys in the harness debug output.

* fix(xrpl): reject duplicate settlements with a settlement cache

Concurrent /settle calls carrying the same signed blob each passed
verification, and because XRPL submission is idempotent on the
transaction hash, submitAndWait resolved the same validated tesSUCCESS
for every caller. The facilitator therefore returned success to all of
them, letting a client access the resource N times while paying once.

Add an in-memory SettlementCache (mirroring the SVM one) keyed on the
signed transaction hash. settle() checks and inserts the key
synchronously between re-verification and submission, so concurrent
duplicates are serialized: the first proceeds, the rest return a
duplicate_settlement error.

Unlike Solana's protocol-fixed blockhash lifetime, an XRPL transaction
stays landable until its LastLedgerSequence, which the scheme derives
from maxTimeoutSeconds. Each entry's retention is sized to that window
(plus a margin) rather than a flat interval, so an entry cannot be
evicted while a slow-to-validate duplicate could still pass
re-verification. Document the mitigation as REQUIRED in the spec,
including the per-process scope and the shared-store requirement for
horizontally scaled facilitators.
Follow-up to #2801, implementing the maintainer suggestion to add XRPL
as an optional network on the x402.org testnet facilitator.

Unlike the other optional networks, XRPL is gated on an explicit
FACILITATOR_XRPL_ENABLED=true flag rather than a private key: in the
XRPL exact scheme the payer signs the transaction and pays its fee, so
the facilitator needs no key or funds — it only verifies and submits
the pre-signed blob. An optional FACILITATOR_XRPL_TESTNET_WS_URL
override is supported for deployments that prefer their own node over
the default public testnet endpoint, mirroring the e2e facilitator's
XRPL_WS_URL option.
* Update docs/sdk-features.md

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/sdk-features.md

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/schemes/exact.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…2856)

* docs: add XRPL to buyer quickstart, network lists, and facilitators

Complements #2854 (XRPL Setup in exact.mdx + sdk-features tables) with
the remaining pages, mirroring how NEAR was documented in #2771:

- quickstart-for-buyers: install line, XRPL signer section, multi-scheme
  registration example, and the summary package list
- schemes/overview: add XRPL to the network implementations sentence
- network-and-token-support: add the xrpl:<networkId> CAIP-2 identifier
- dev-tools/facilitators: list the T54 XRPL facilitator (mainnet and
  testnet), which previously appeared on the ecosystem page removed in
  #2794

* docs: add XRPL to the token support table

The Token Support ecosystem table and its intro sentence stopped at
Concordium; add the XRPL row (XRP or any issued currency, transferred
via a payer-signed Payment transaction) alongside the CAIP-2 identifier
added in the previous commit.

* docs: add XRPL to the network support summary bullet

The Summary list at the bottom of network-and-token-support.mdx parallels
the intro sentence updated in the previous commit; bring it in line so
both lists end with the same network set.
* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/core-concepts/network-and-token-support.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* SIWX configured-origin fix

* py+go

* updated docs
* harden channel storage

* handle failures

* few more fixes

* go

* py

* fix fmt
* Update docs/advanced-concepts/lifecycle-hooks.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/advanced-concepts/lifecycle-hooks.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
#2884)

* fix(evm): auto-wrap any eth_account BaseAccount, not just LocalAccount

_wrap_if_local_account only checked isinstance(signer, LocalAccount), so
third-party wallet-provider adapters that extend eth_account's abstract
BaseAccount directly (e.g. Coinbase AgentKit's EvmWalletSigner, or any
custom-custody signer) were passed through unwrapped instead of being
wrapped in EthAccountSigner. Calling such a signer's sign_typed_data
with x402's positional (domain, types, primary_type, message) convention
then misassigns arguments against its eth_account-style keyword signature,
raising a KeyError deep in eth_account.messages.encode_typed_data.

Broaden the check to BaseAccount (LocalAccount's own parent class) in all
three duplicated occurrences: exact, upto, and batch_settlement client
schemes. Adds regression tests with a minimal BaseAccount-only signer.

Reproduced against a real x402 v2 GatewayWalletBatched payment requirement
signed by an AWS KMS-backed signer wrapped in a BaseAccount subclass.

Note: most of this change was written with AI assistance (Claude Code) and
reviewed/verified by me before submission, per this repo's AI-assisted
contribution guidelines.

* docs(changelog): add fragment for #2884
* feat(extensions): add code and cause to SIWx failure results

* refactor(extensions): align SIWx validation result with verify response shape

* remove cause, also align SIWxVerifyResult with facilitator verify

---------

Co-authored-by: vraspar <v2parikh@uwaterloo.ca>
* Update docs/extensions/sign-in-with-x.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/extensions/sign-in-with-x.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/extensions/sign-in-with-x.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/extensions/sign-in-with-x.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* py SIWX structured-error

* go SIWX structured-error
The examples index was last updated in #345 (2025-08-18). The v2
restructure in #705 rewrote every example under examples/typescript
but left it untouched: of its 20 entries, 13 point at directories
that no longer exist, and 29 of the 35 examples on disk are missing.

Rebuild all four listings from what is on disk, add indexes for
fullstack/ and facilitator/, and correct claims that no longer hold:
custom/ does not use @x402/core alone, and Fastify now has a package.
* limit s array size

* go/py

* add changeset

* fix fmt
* Update docs/extensions/builder-code.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/extensions/builder-code.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* fix(python): preserve streaming bodies on payment retry

Buffer request content before the initial send so a 402 retry replays the same body.

* chore(python): use pull request number for changelog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.